/**
 * `debounce`简单的防抖函数实现
 *
 * @param {function} cb 要执行的回调函数
 * @param {number} delay 要等待的防抖延迟时间
 * @returns {function}
 */
const debounce = function(cb, delay) {
    // 参数检查
    //   cb：function
    //   delay：number
    if (!cb || toString.call(cb) !== '[object Function]') {
        throw new Error(`${cb} is not a function.`)
    }
    // 没有传 delay 参数时（包括等于0）
    if (!delay) {
        delay = 500 // 设置默认延时
    }
    // delay 参数须为正整数
    else if (!Number.isInteger(delay) || delay < 0) {
        throw new Error(`${delay} is invalid as optional parameter [delay]`)
    }

    // 定时器
    let timer = null
    
    // 返回debounce包装过的执行函数
    return function(...args) {
        // 如果存在定时器
        if (timer) {
            // 清除定时器，
            // 即：忽略之前的触发
            clearTimeout(timer)
        }

        // 设置定时器
        timer = setTimeout(() => {
            // 当到了设定的时间：
            //   清除本次定时器，
            //   并执行函数
            clearTimeout(timer)
            timer = null
            cb.call(null, ...args)
        }, delay);
    }
}